/* 
 * File:   algebra.h
 * Author: gustavo
 *
 * Created on June 4, 2011, 11:26 AM
 */

#ifndef ALGEBRA_H
#define	ALGEBRA_H

#include "../matrix/matrix.h"

#ifdef	__cplusplus
extern "C" {
#endif
	
	void imp_algebra_SVD(ImpMatrix * A, ImpMatrix ** U, ImpMatrix ** Q, ImpMatrix ** V);


	void imp_algebra_max(ImpMatrix * Mat, ImpMatrix ** Max, ImpMatrix ** Ind);
	void imp_algebra_min(ImpMatrix * Mat, ImpMatrix ** Min, ImpMatrix ** Ind);
	
	void imp_algebra_append_right(ImpMatrix * src_left, ImpMatrix * src_right, ImpMatrix ** dest);
	void imp_algebra_transpose(ImpMatrix * A, ImpMatrix ** T);

	/**
	 * Compute the somatory of the columns
	 * @param A: is a m by n input matrix.
	 * @param S: is a 1 by n somatory matrix. S must to be previously allocated.
	 */
	void imp_algebra_sum(ImpMatrix * A, ImpMatrix ** Sum);

	/**
	 * Compute Add = A + B
	 * @param A: a m by n input matrix.
	 * @param B: a m by n input matrix.
	 * @param Add: the result of A+B. Add is a m by n matrix and have to be previously allocated.
	 */
	void imp_algebra_add(ImpMatrix * A, ImpMatrix * B, ImpMatrix ** Add);
	/**
	 * Compute Sub = A - B
	 * @param A: a m by n input matrix.
	 * @param B: a m by n input matrix.
	 * @param Add: the result of A-B. Add is a m by n matrix and have to be previously allocated.
	 */
	void imp_algebra_sub(ImpMatrix * A, ImpMatrix * B, ImpMatrix ** Sub);
	
	void imp_algebra_pow(ImpMatrix * A, real pot);

	/**
	 * Compute Mult = A * B
	 * @param A: a m by n input matrix.
	 * @param B: a n by c input matrix.
	 * @param Mult: the result of A * B. Mult is a m by c matrix and have to be previously allocated.
	 */
	void imp_algebra_mult(ImpMatrix * A, ImpMatrix * B, ImpMatrix ** Mult);

	/**
	 * Compute the upper triangle matrix of A by row elimination.
	 * @param A: a m by n input matrix.
	 * @param U: The Upper Triangle m by n ImpMatrix. It must to be previously allocated.
	 */
	void imp_algebra_upper_triangle(ImpMatrix * A, ImpMatrix ** Upper);

	real imp_algebra_determinant(ImpMatrix * A);

	/**
	 * Compute the lower triangle matrix of A by row elimination.
	 * @param A: a m by n input matrix.
	 * @param L: The Lower Triangle m by n ImpMatrix. It must to be previously allocated.
	 */
	void imp_algebra_lower_triangle(ImpMatrix * A, ImpMatrix ** Lower);

	/**
	 * Compute the LU factorization, diagonal D and the permutations matrix P of the matrix A.
	 *		<pre> A = PLDU </pre>
	 * @param A: input matrix.
	 * @param P: permutations matrix. If P is NULL, the function will not
	 *			 compute this matrix.
	 * @param L: Lower Triangle matrix.
	 * @param D: Diagonal matrix with the pivots. If D is NULL, the function
	 *			 will not compute this matrix.
	 * @param U: Upper Triangle matrix.
	 */
	void imp_algebra_LU(ImpMatrix * A, ImpMatrix ** P, ImpMatrix ** L, ImpMatrix ** D, ImpMatrix ** U);

	/**
	 * Compute the Reduced Row Echelon Form (rref) of matrix A.
	 * @param A: input matrix.
	 * @param R: reduced row echelon form.
	 * @param idp: a flag vector about the linearity of the columns.
	 *		<br>Zero (0) indicates a dependent column.
	 *		<br>One (1) indicates a independent column.
	 * @param rank the rank of the matrix.
	 */
	void imp_algebra_rref(ImpMatrix * A, ImpMatrix ** R, ImpMatrix ** idp, ImpMatrix ** Null, int * rank);

	/**
	 * Compute the null space of M
	 * @param M: input matrix
	 * @param N: null space
	 */
	void imp_algebra_null(ImpMatrix * M, ImpMatrix ** N);


#ifdef	__cplusplus
}
#endif

#endif	/* ALGEBRA_H */

